<?php

namespace App\Http\Controllers\Admin\Finance;

use App\Exports\SalaryExport;
use App\Http\Controllers\Controller;
use App\Http\Requests\finance\SalaryRequest;
use App\Imports\SalaryImport;
use App\Models\finance\SalaryDayModel;
use App\Models\finance\SalaryDecModel;
use App\Models\finance\SalaryModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

class Salary extends Controller
{
    use SalaryRequest;

    /**
     * Notes:列表
     * User: xiangzi
     * Date: 2024/9/5
     * Time: 14:35
     * @return \Illuminate\Http\JsonResponse
     */
    public function list(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $staff_name = $request->input('staff_name', '');
        $dept_id = $request->input('dept_id', '');
        $month = $request->input('month', '');
        $status = $request->input('status', '');

        $query = SalaryModel::query()->withWhereHas('staff', function ($query) use ($staff_name, $dept_id) {
            $query->with('role');
            if($staff_name){
                $query->where('name', 'like', '%' . $staff_name . '%');
            }
            if($dept_id){
                $query->where('dept_id', $dept_id);
            }
        });

        if($month){
            $query = $query->where('month', $month);
        }

        if($status){
            $query = $query->where('status', $status);
        }


        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $company_total = 0; $actual_total = 0;
        $list = $items->map(function($item) {
            $res = [
                'id' => $item->id,
                'month' => $item->month,
                'staff_name' => $item->staff ? $item->staff->name : '',
                'staff_name_en' => $item->staff ? $item->staff->staff_name_en : '',
                'staff_role' => $item->staff->role ? $item->staff->role->name : '',
                'job_level' => $item->staff ? $item->staff->job_level : '',
                'employment_start_date' => $item->staff ? $item->staff->employment_start_date : '',
                'resignation_date' => $item->staff ? $item->staff->resignation_date : '',
                'monthly_base_salary' => $item->staff ? $item->staff->monthly_base_salary : '',
                'work_days' => $item->work_days,
                'actual_work_days' => $item->actual_work_days,
                'rest_over_days' => $item->rest_over_days,
                'holiday_over_days' => $item->holiday_over_days,
                'company_yl' => $item->company_yl,
                'company_yil' => $item->company_yil,
                'company_sy' => $item->company_sy,
                'company_gs' => $item->company_gs,
                'company_syu' => $item->company_syu,
                'company_gjj' => $item->company_gjj,
                'company_sbgjj_add' => $item->company_sbgjj_add,
                'company_sbgjj_back' => $item->company_sbgjj_back,
                'company_total' => $item->company_total,
                'salary_base' => $item->salary_base,
                'salary_gwjt' => $item->salary_gwjt,
                'salary_jbgz' => $item->salary_jbgz,
                'salary_cb' => $item->salary_cb,
                'salary_txbz' => $item->salary_txbz,
                'salary_qqj' => $item->salary_qqj,
                'salary_bmf' => $item->salary_bmf,
                'salary_jj' => $item->salary_jj,
                'salary_bt' => $item->salary_bt,
                'salary_total' => $item->salary_total,
                'staff_yl' => $item->staff_yl,
                'staff_yil' => $item->staff_yil,
                'staff_sy' => $item->staff_sy,
                'staff_gjj' => $item->staff_gjj,
                'staff_tax' => $item->staff_tax,
                'staff_other' => $item->staff_other,
                'staff_sbgjj_add' => $item->staff_sbgjj_add,
                'staff_sbgjj_back' => $item->staff_sbgjj_back,
                'staff_total' => $item->staff_total,
                'salary' => $item->salary,
                'remarks' => $item->remarks
            ];
            return $res;
        });

        foreach ($list as $item) {
            $company_total += $item['company_total'];
            $actual_total += $item['salary'];
        }

        //每月天数
        $month_days = SalaryDayModel::query()->where('month', $month)->value('day');

        return $this->success(['list' => $list, 'total' => $total, 'company_total' => $company_total, 'actual_total' => $actual_total, 'month_days' => $month_days ?? '']);
    }

    /**
     * Notes:每月应出勤天数
     * User: xiangzi
     * Date: 2024/9/23
     * Time: 15:22
     * @return \Illuminate\Http\JsonResponse
     */
    public function month_day(Request $request)
    {
        $auth = $request->get('auth');
        $params = $request->all();

        $check_res = self::month_day_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        $model = new SalaryDayModel();
        $model->month = $params['month'];
        $model->day = $params['day'];
        $model->created_admin_id = $auth->id;
        $model->save();

        return $this->success();
    }

    /**
     * Notes:修改实际考勤
     * User: xiangzi
     * Date: 2024/9/23
     * Time: 15:22
     * @return \Illuminate\Http\JsonResponse
     */
    public function actual_day(Request $request, $id)
    {
        $day = $request->input('day', '');

        if($day == ''){
            return $this->error('天数不能为空');
        }

        $model = SalaryModel::find($id);
        if (!$model) {
            return $this->error('数据不存在');
        }

        $model->actual_work_days = $day;
        $model->save();

        return $this->success();
    }

    /**
     * Notes:减薪
     * User: xiangzi
     * Date: 2024/9/23
     * Time: 15:22
     * @return \Illuminate\Http\JsonResponse
     */
    public function dec(Request $request, $id)
    {
        $auth = $request->get('auth');
        $params = $request->all();

        $check_res = self::salary_dec_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        $insert = [];
        foreach ($params['list'] as $item) {
            $insert[] = [
                'salary_id' => $id,
                'salary_name_id' => $item['salary_name_id'],
                'amount' => $item['amount'],
                'remarks' => $item['remarks'] ?? '',
                'created_admin_id' => $auth->id,
                'created_at' => date('Y-m-d H:i:s')
            ];
        }

        SalaryDecModel::insert($insert);

        return $this->success();
    }

    /**
     * Notes:补贴
     * User: xiangzi
     * Date: 2024/9/23
     * Time: 15:59
     * @return \Illuminate\Http\JsonResponse
     */
    public function subsidy(Request $request, $id){
        $params = $request->all();

        $check_res = self::subsidy_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        $model = SalaryModel::find($id);
        if (!$model) {
            return $this->error('数据不存在');
        }

        $model->salary_bt = $params['amount'];
        $model->save();

        return $this->success();
    }


    /**
     * Notes:应发小计
     * User: xiangzi
     * Date: 2024/9/23
     * Time: 15:59
     * @return \Illuminate\Http\JsonResponse
     */
    public function total(Request $request, $id){
        $params = $request->all();

        $check_res = self::subsidy_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        $model = SalaryModel::find($id);
        if (!$model) {
            return $this->error('数据不存在');
        }

        $other_total = $model->salary_base + $model->salary_gwjt +$model->salary_jbgz +$model->salary_cb +$model->salary_txbz +$model->salary_qqj +$model->salary_bt +$model->salary_bmf;

        if($params['amount'] < $other_total){
            return $this->error('应发小计不能小于其他应发明细合计');
        }

        $model->staff_total = $params['amount'];
        $model->salary_jj = round($params['amount'] - $other_total, 2);
        $model->save();

        return $this->success();
    }

    /**
     * Notes:明细
     * User: xiangzi
     * Date: 2024/9/24
     * Time: 9:50
     * @return \Illuminate\Http\JsonResponse
     */
    public function detail(Request $request)
    {
        $id = $request->input('id', 0);

        $model = SalaryModel::with('staff')->find($id);
        if (!$model) {
            return $this->error('数据不存在');
        }

        $return = [
            'staff_name' => $model->staff ? $model->staff->name : '',
            'month' => $model->month,
            'work_days' => $model->work_days,
            'actual_work_days' => $model->actual_work_days,
            'rest_over_days' => $model->rest_over_days,
            'holiday_over_days' => $model->holiday_over_days,
            'monthly_base_salary' => $model->staff ? $model->staff->monthly_base_salary : '',
            'salary_gwjt' => $model->salary_gwjt,
            'company_total' => $model->company_total
        ];

        $list = [
            ['name' => '实得基本工资', 'amount' => '+' . $model->salary_base, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_base'],
            ['name' => '岗位津贴', 'amount' => '+' . $model->salary_gwjt, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_gwjt'],
            ['name' => '加班工资', 'amount' => '+' . $model->salary_jbgz, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_jbgz'],
            ['name' => '餐补', 'amount' => '+' . $model->salary_cb, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_cb'],
            ['name' => '通讯补助', 'amount' => '+' . $model->salary_txbz, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_txbz'],
            ['name' => '全勤奖', 'amount' => '+' . $model->salary_qqj, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_qqj'],
            ['name' => '保密费', 'amount' => '+' . $model->salary_bmf, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_bmf'],
            ['name' => '奖金', 'amount' => '+' . $model->salary_jj, 'type' => 'fixed', 'id' => $model->id, 'params' => 'salary_jj'],
            ['name' => '养老保险', 'amount' => '-' . $model->staff_yl, 'type' => 'fixed', 'id' => $model->id, 'params' => 'staff_yl'],
            ['name' => '医疗保险', 'amount' => '-' . $model->staff_yil, 'type' => 'fixed', 'id' => $model->id, 'params' => 'staff_yil'],
            ['name' => '失业保险', 'amount' => '-' . $model->staff_sy, 'type' => 'fixed', 'id' => $model->id, 'params' => 'staff_sy'],
            ['name' => '公积金', 'amount' => '-' . $model->staff_gjj, 'type' => 'fixed', 'id' => $model->id, 'params' => 'staff_gjj'],
            ['name' => '个人所得税', 'amount' => '-' . $model->staff_tax, 'type' => 'fixed', 'id' => $model->id, 'params' => 'staff_tax'],
        ];

        $dec = SalaryDecModel::with('salary_name')->where('salary_id', $id)->get();

        foreach ($dec as $item) {
            $list[] = [
                'name' => $item->salary_name ? $item->salary_name->name : '',
                'amount' => '-' . $item->amount,
                'type' => 'dec',
                'id' => $item->id,
            ];
        }

        $return['list'] = $list;
        return $this->success($return);
    }

    /**明细编辑
     * Notes:
     * User: xiangzi
     * Date: 2024/9/24
     * Time: 9:57
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(Request $request, $id)
    {
        $params = $request->all();

        $check_res = self::edit_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        if($params['type'] == 'fixed'){
            $model = SalaryModel::find($id);
            if (!$model) {
                return $this->error('数据不存在');
            }

            if(!isset($params['params'])){
                return $this->error('没有修改项');
            }

            $model->{$params['params']} = $params['amount'];
            $model->save();
        }else{
            $model = SalaryDecModel::find($id);
            if (!$model) {
                return $this->error('数据不存在');
            }

            $model->amount = $params['amount'];
            $model->save();
        }

        return $this->success();

    }

    /**
     * Notes:明细删除
     * User: xiangzi
     * Date: 2024/9/24
     * Time: 9:59
     * @return \Illuminate\Http\JsonResponse
     */
    public function delete(int $id){
        $model = SalaryDecModel::find($id);
        if(!$model) {
            return $this->error('记录不存在');
        }
        $model->delete();
        return $this->success();
    }

    /**
     * Notes:备注
     * User: xiangzi
     * Date: 2024/10/12
     * Time: 下午5:35
     * @return \Illuminate\Http\JsonResponse
     */
    public function remarks(Request $request, $id)
    {
        $remarks = $request->input('remarks', '');

        if($remarks == ''){
            return $this->error('备注不能为空');
        }else{
            $model = SalaryModel::find($id);
            if (!$model) {
                return $this->error('数据不存在');
            }
            $model->remarks = $remarks;
            $model->save();
            return $this->success();
        }

    }

    public function export(Request $request)
    {
        $ids = $request->input('ids', []);
        if(empty($ids)){
            return $this->error('请选择要导出的数据');
        }

        $list = SalaryModel::with(['staff' => function($query){
            $query->with('role');
        }])->whereIn('id', $ids)->get();

        $list = $list->map(function($item){
            $res = [
                'staff_name' => $item->staff ? $item->staff->name : '',
                'staff_name_en' => $item->staff ? $item->staff->staff_name_en : '',
                'staff_role' => $item->staff->role ? $item->staff->role->name : '',
                'job_level' => $item->staff ? $item->staff->job_level : '',
                'employment_start_date' => $item->staff ? $item->staff->employment_start_date : '',
                'resignation_date' => $item->staff ? $item->staff->resignation_date : '',
                'monthly_base_salary' => $item->staff ? $item->staff->monthly_base_salary : '',
                'work_days' => $item->work_days,
                'actual_work_days' => $item->actual_work_days,
                'rest_over_days' => $item->rest_over_days,
                'holiday_over_days' => $item->holiday_over_days,
                'company_yl' => $item->company_yl,
                'company_yil' => $item->company_yil,
                'company_sy' => $item->company_sy,
                'company_gs' => $item->company_gs,
                'company_syu' => $item->company_syu,
                'company_gjj' => $item->company_gjj,
                'company_sbgjj_add' => $item->company_sbgjj_add,
                'company_sbgjj_back' => $item->company_sbgjj_back,
                'company_total' => $item->company_total,
                'salary_base' => $item->salary_base,
                'salary_gwjt' => $item->salary_gwjt,
                'salary_jbgz' => $item->salary_jbgz,
                'salary_cb' => $item->salary_cb,
                'salary_txbz' => $item->salary_txbz,
                'salary_qqj' => $item->salary_qqj,
                'salary_bmf' => $item->salary_bmf,
                'salary_jj' => $item->salary_jj,
                'salary_bt' => $item->salary_bt,
                'salary_total' => $item->salary_total,
                'staff_yl' => $item->staff_yl,
                'staff_yil' => $item->staff_yil,
                'staff_sy' => $item->staff_sy,
                'staff_gjj' => $item->staff_gjj,
                'staff_tax' => $item->staff_tax,
                'staff_other' => $item->staff_other,
                'staff_sbgjj_add' => $item->staff_sbgjj_add,
                'staff_sbgjj_back' => $item->staff_sbgjj_back,
                'staff_total' => $item->staff_total,
                'salary' => $item->salary,
                'remarks' => $item->remarks
            ];
            return $res;
        });

        return Excel::download(new SalaryExport($list), 'salary.xlsx');
    }


    public function import(Request $request)
    {
        $auth = $request->get('auth');
        $file = $request->file('file');
        if(!$file){
            return $this->error('请选择文件');
        }

        $import = new SalaryImport();
        Excel::import($import, $file);


        $res = $import->get_result();

        if(isset($res->error) && $res->error){
            return $this->error(implode(',', $res->error));
        }

        $lines = $res->lines;

        DB::beginTransaction();
        try {
            foreach ($lines as $line){
                $staff = new SalaryModel();
                $staff->month = date('Y-m', strtotime('last month'));
                foreach ($line as $k => $v){
                    $staff->$k = $v;
                }
                $staff->created_admin_id = $auth->id;
                $staff->save();
            }
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return  $this->success();


    }



}
